package com.dirk.happie.network;

import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.Reader;
import java.io.UnsupportedEncodingException;
import java.lang.reflect.Type;
import java.util.ArrayList;
import java.util.List;

import org.apache.http.HttpEntity;
import org.apache.http.HttpResponse;
import org.apache.http.HttpStatus;
import org.apache.http.NameValuePair;
import org.apache.http.client.HttpClient;
import org.apache.http.client.entity.UrlEncodedFormEntity;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.impl.client.DefaultHttpClient;
import org.apache.http.message.BasicNameValuePair;
import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;

import android.app.Activity;
import android.app.ProgressDialog;
import android.os.AsyncTask;
import android.util.Log;
import android.widget.Toast;

import com.dirk.happie.R;
import com.dirk.happie.beans.CategoryBean;
import com.dirk.happie.utils.App;
import com.dirk.happie.utils.Keys;
import com.google.gson.Gson;
import com.google.gson.reflect.TypeToken;

public class GetCategoriesTask extends AsyncTask<String, Void, List<CategoryBean>> {
	private ProgressDialog pDialog;
	private RequestCompleteListener<List<CategoryBean>> listener = null;
	private Activity context;
	private App mApp;

	public GetCategoriesTask() {
	}

	public GetCategoriesTask(Activity context) {
		this.context = context;
		pDialog = new ProgressDialog(context);
		pDialog.setCancelable(true);
		pDialog.setMessage(context.getString(R.string.gen_loading));
		pDialog.setTitle(context.getString(R.string.gen_please_wait));
		mApp = (App) context.getApplication();
	}

	public void setRequestCompleteListener(RequestCompleteListener<List<CategoryBean>> listener) {
		this.listener = listener;
	}

	@Override
	protected void onPreExecute() {
		// TODO Auto-generated method stub

		pDialog.show();

		super.onPreExecute();
	}

	/*
	 * Do all the network IO and time-consuming parsing in here, this method
	 * will be invoked in its own thread, not blocking the UI.
	 */
	@Override
	protected List<CategoryBean> doInBackground(String... params) {

		List<CategoryBean> response = null;
		InputStream source = retrieveStream(Keys.CATEGORIES_URL, params[0]);

		Gson gson = new Gson();

		if (source != null) {
			Reader reader = new InputStreamReader(source);

			// CategoryBean[] response = gson.fromJson(reader,
			// CategoryBean[].class);
			Type listType = new TypeToken<List<CategoryBean>>() {
			}.getType();
			response = gson.fromJson(reader, listType);
			if (response.get(0).getCategoryId() != null) {
				return response;
			} else {
				response = null;
				HttpClient client = new DefaultHttpClient();
				String result = null;
				try {

					HttpPost request = new HttpPost(Keys.CATEGORIES_URL);
					List<NameValuePair> nameValuePairs = new ArrayList<NameValuePair>(2);

					nameValuePairs.add(new BasicNameValuePair("company", params[0]));
					nameValuePairs.add(new BasicNameValuePair("_lang", mApp.getLanguage()));

					try {
						request.setEntity(new UrlEncodedFormEntity(nameValuePairs));
					} catch (UnsupportedEncodingException e1) {
						// TODO Please log this
					}

					HttpResponse httpResponse = client.execute(request);

					HttpEntity entity = httpResponse.getEntity();
					// If the response does not enclose an entity, there is no
					// need
					// to worry about connection release

					if (entity != null) {

						// A Simple JSON Response Read
						InputStream instream = null;
						try {
							instream = entity.getContent();

							result = NetworkManager.convertStreamToString(instream);

							Log.i("GetCategories", result);

							JSONArray jsonArray = new JSONArray(result);

							JSONObject json = jsonArray.getJSONObject(0);

							if (json.has("apimsg")) {
								if (listener != null) {
									listener.onFailure(json.optString("apimsg", ""));
								}
							}

							if (json.has("error")) {
								if (listener != null) {
									listener.onFailure(json.optString("error", ""));
								}
							}

						} catch (JSONException e) {
							// TODO Auto-generated catch block
							e.printStackTrace();
						} finally {
							// Closing the input stream will trigger connection
							// release
							try {
								instream.close();
							} catch (IOException e) {
								// TODO Auto-generated catch block
								e.printStackTrace();
							}
						}
					}

				} catch (IOException ex) {
					// properly log your exception, don't just printStackTrace()
					// as you can't pinpoint the location and it might be cut
					// off
					Log.e("LOGIN", "failed to log in", ex);
				} finally {
					client.getConnectionManager().shutdown();
				}
			}
		} else {
			context.runOnUiThread(new Runnable() {

				@Override
				public void run() {
					Toast.makeText(context, context.getString(R.string.no_connection), Toast.LENGTH_SHORT).show();

				}
			});
		}

		return response;

	}

	private InputStream retrieveStream(String url, String params) {
		DefaultHttpClient client = new DefaultHttpClient();
		HttpPost getRequest = new HttpPost(url);
		List<NameValuePair> nameValuePairs = new ArrayList<NameValuePair>(2);

		nameValuePairs.add(new BasicNameValuePair("company", params));
		nameValuePairs.add(new BasicNameValuePair("_lang", mApp.getLanguage()));

		try {
			getRequest.setEntity(new UrlEncodedFormEntity(nameValuePairs));
		} catch (UnsupportedEncodingException e1) {
			// TODO Please log this
		}
		InputStream in = null;
		try {

			HttpResponse getResponse = client.execute(getRequest);
			final int statusCode = getResponse.getStatusLine().getStatusCode();

			if (statusCode != HttpStatus.SC_OK) {
				Log.w(getClass().getSimpleName(), "Error " + statusCode + " for URL " + url);
				return null;
			}

			HttpEntity getResponseEntity = getResponse.getEntity();
			in = getResponseEntity.getContent();
			// String r = NetworkManager.convertStreamToString(in);
			//
			// Log.i("", "");

		} catch (IOException e) {
			getRequest.abort();
			Log.w(getClass().getSimpleName(), "Error for URL " + url, e);
		}

		return in;
	}

	/*
	 * This again runs on the UI thread, so only do here what really needs to
	 * run on the UI thread.
	 */
	@Override
	protected void onPostExecute(List<CategoryBean> response) {
		if (listener != null && response != null) {
			listener.onSuccess(response);
		}
		pDialog.dismiss();
	}
}